use stdx::default::default;

use std::collections::HashMap;
use std::sync::LazyLock;

static PHRASE_TABLE: LazyLock<HashMap<&'static str, &'static str>> = LazyLock::new(|| {
    let mut ans: HashMap<&'static str, &'static str> = default();
    let file_content = include_str!(concat!(env!("OUT_DIR"), "/wadegiles_phrases.txt"));
    for line in file_content.lines() {
        let (key, pinyin) = line.split_once(':').unwrap();
        ans.insert(key, pinyin);
    }
    ans
});

static CHAR_TABLE: LazyLock<HashMap<char, &'static str>> = LazyLock::new(|| {
    let mut ans: HashMap<char, &'static str> = default();
    let file_content = include_str!(concat!(env!("OUT_DIR"), "/wadegiles_chars.txt"));
    for line in file_content.lines() {
        let (key, pinyin) = line.split_once(':').unwrap();
        let key = key.chars().next().unwrap();
        ans.insert(key, pinyin);
    }
    ans
});

#[must_use]
pub fn converter(input: &str) -> String {
    if let Some(value) = PHRASE_TABLE.get(input).copied() {
        return capitalize(value);
    }

    let table = &*CHAR_TABLE;
    let mut ans = String::new();
    for ch in input.chars() {
        match table.get(&ch).copied() {
            Some(value) => {
                if ans.is_empty() {
                    ans = capitalize(value);
                } else {
                    ans.push(' ');
                    ans.push_str(value);
                }
            }
            None => return String::new(),
        }
    }
    ans
}

fn capitalize(s: &str) -> String {
    let mut chars = s.chars();
    match chars.next() {
        None => String::new(),
        Some(f) => f.to_uppercase().chain(chars).collect(),
    }
}
